import datetime

import logging
from flask import current_app
from flask import g, jsonify
from flask import  request

from iHome import db, redis_store
from iHome.models import House, Order
from iHome.utils.commons import login_required
from iHome.utils.response_code import RET
# from migrations.env import logger
from . import api




# 1.添加订单
@api.route('/orders', methods=["POST"])
@login_required
def add_order():
    """
    添加订单
    :return:
    """
    # 1.获取到当前用户的id
    user_id = g.user_id
    # 2.获取到传入的参数
    params = request.get_json()
    house_id = params.get('house_id')
    start_date_str = params.get('start_date')
    end_date_str = params.get('end_date')

    # 3.校验参数
    if not all([house_id, start_date_str, end_date_str]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
    try:
        start_date = datetime.datetime.strptime(start_date_str, "%Y-%m-%d")
        end_date = datetime.datetime.strptime(end_date_str, "%Y-%m-%d")
        assert start_date < end_date, Exception('开始日期大于结束日期')
    # 4.计算出入住天数
        days = (end_date - start_date).days
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    # 5.判断房屋是否存在
    house = House.query.get(house_id)
    if not house:
        return jsonify(errno=RET.NODATA, errmsg='房屋不存在')

    # 6.判断房屋是否是当前登录用户的
    if user_id == house.user_id:
        return jsonify(errno=RET.ROLEERR, errmsg='不能预订自己的房屋')

    # 7.查询是否存在冲突的订单
    try:
        filters = [Order.house_id == house_id, Order.begin_date < end_date, Order.end_date > start_date]
        count = Order.query.filter(*filters).count()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据查询错误')

    if count > 0:
        return jsonify(errno=RET.DATAERR, errmsg='该房屋已被预订')

    amount = days * house.price
    # 8.生成订单的模型
    order = Order()
    order.user_id = user_id
    order.house_id = house_id
    order.begin_date = start_date
    order.end_date = end_date
    order.days = days
    order.house_price = house.price
    order.amount = amount

    try:
        db.session.add(order)
        db.session.commit()
    except Exception as e:
        logging.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='数据保存出错')

    return jsonify(errno=RET.OK, errmsg='OK', data={"order_id": order.id})







#2.获取用户订单列表
@api.route('/orders')
@login_required
def user_orders():
    """
    查询订单,通过参数判断要查询房东/房客的订单
    :return:
    """

    # 获取相关参数
    user_id = g.user_id
    role = request.args.get('role')

    if not role:
        return jsonify(errno=RET.PARAMERR, errmsg='参数有误')

    if role == "custom":
        # 查询当前自己下了哪些订单
        orders = Order.query.filter_by(user_id=user_id).order_by(Order.create_time.desc())
    else:
        # 查询自己房屋都有哪些订单
        houses = House.query.filter_by(user_id=user_id).all()
        house_ids = [house.id for house in houses]
        orders = Order.query.filter(Order.house_id.in_(house_ids)).order_by(Order.create_time.desc())

    orders_dict = []

    for order in orders:
        orders_dict.append(order.to_dict())
    return jsonify(errno=RET.OK, errmsg="请求成功", data={"orders": orders_dict})







#3.接单和拒单后台实现
@api.route('/orders', methods=["PUT"])
@login_required
def change_order_status():
    """
    1. 接受参数：order_id
    2. 通过order_id找到指定的订单，(条件：status="待接单")
    3. 修改订单状态
    4. 保存到数据库
    5. 返回
    :return:
    """
    user_id = g.user_id
    data_json = request.json
    # 取到订单号
    order_id = data_json.get("order_id")
    action = data_json.get("action")

    if not all([order_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # accept / reject
    if action not in ("accept", "reject"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 2. 查询订单
    try:
        order = Order.query.filter(Order.id == order_id, Order.status == "WAIT_ACCEPT").first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询错误")

    if not order:
        return jsonify(errno=RET.NODATA, errmsg="未查询到订单")

    # 查询当前订单的房东是否是当前登录用户，如果不是，不允许操作
    if user_id != order.house.user_id:
        return jsonify(errno=RET.ROLEERR, errmsg="不允许操作")

    # 3 更改订单的状态
    if "accept" == action:
        # 接单
        order.status = "WAIT_COMMENT"
    elif "reject" == action:
        order.status = "REJECTED"
        # 取出原因
        reason = data_json.get("reason")
        if not reason:
            return jsonify(errno=RET.PARAMERR, errmsg="请填写拒单原因")
        # 保存拒单原因
        order.comment = reason

    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="保存数据失败")

    return jsonify(errno=RET.OK, errmsg="OK")






# 4.评论订单
@api.route('/orders/comment', methods=["PUT"])
@login_required
def set_order_comment():
    """
        评论订单
        :param order_id:
        :return:
        """
    #1.获取参数&判断参数
    data_dict = request.get_json()
    comment = data_dict.get("comment")
    order_id = data_dict.get("order_id")
    if not comment:
        return jsonify(errno=RET.PARAMERR, errmsg="请输入评论内容")
 
    # 2.通过订单id查询出订单模型
    try:
        order = Order.query.filter(Order.id == order_id, Order.status=="WAIT_COMMENT").first()
        house = order.house
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据库错误")

    #3.更新数据
    house.order_count += 1
    order.status = "COMPLETE"
    order.comment = comment
    #4.更新数据库
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        logging.error(e)
        return jsonify(errno=RET.NODATA, errmsg="跟新数据库失败")

    #5.删除redis中缓存的房屋详情信息,因为房屋详情信息已经更新
    try:
        redis_store.delete("house_info_" + house.id)
    except Exception as e:
        logging.error(e)

    return jsonify(errno=RET.OK, errmsg="OK")








